#define  _CRT_SECURE_NO_WARNINGS
#include "concurrentalloc.h"
void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> malloc_costtime = 0;
    std::atomic<size_t> free_costtime = 0;

    for (size_t k = 0; k < nworks; ++k)
    {
        vthread[k] = std::thread([&]() {  // 移除了未使用的[k]捕获
            std::vector<void*> v;
            v.reserve(ntimes);

            for (size_t j = 0; j < rounds; ++j)
            {
                size_t begin1 = clock();
                for (size_t i = 0; i < ntimes; i++)
                {
                    v.push_back(malloc((16 + i) % 8192 + 1));
                }
                size_t end1 = clock();

                size_t begin2 = clock();
                for (size_t i = 0; i < ntimes; i++)
                {
                    free(v[i]);
                }
                size_t end2 = clock();
                v.clear();

                malloc_costtime += (end1 - begin1);
                free_costtime += (end2 - begin2);
            }
            });
    }

    for (auto& t : vthread)
    {
        t.join();
    }

    // 显式加载原子值并转换为标准类型
    unsigned long long malloc_time = static_cast<unsigned long long>(malloc_costtime.load());
    unsigned long long free_time = static_cast<unsigned long long>(free_costtime.load());
    unsigned long long total_allocs = static_cast<unsigned long long>(nworks) * rounds * ntimes;

    printf("%llu个线程并发执行%llu轮次，每轮次malloc %llu次: 花费：%llu ms\n",
        static_cast<unsigned long long>(nworks),
        static_cast<unsigned long long>(rounds),
        static_cast<unsigned long long>(ntimes),
        malloc_time);

    printf("%llu个线程并发执行%llu轮次，每轮次free %llu次: 花费：%llu ms\n",
        static_cast<unsigned long long>(nworks),
        static_cast<unsigned long long>(rounds),
        static_cast<unsigned long long>(ntimes),
        free_time);

    printf("%llu个线程并发malloc&free %llu次，总计花费：%llu ms\n",
        static_cast<unsigned long long>(nworks),
        total_allocs,
        malloc_time + free_time);
}

//单轮次申请释放次数 线程数 轮次
void BenchmarkConcurrentMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> malloc_costtime = 0;
    std::atomic<size_t> free_costtime = 0;

    for (size_t k = 0; k < nworks; ++k)
    {
        vthread[k] = std::thread([&]() {  // 移除了未使用的[k]捕获
            std::vector<void*> v;
            v.reserve(ntimes);

            for (size_t j = 0; j < rounds; ++j)
            {
                size_t begin1 = clock();
                for (size_t i = 0; i < ntimes; i++)
                {
                    // 完全保留您的并发分配调用
                    //v.push_back(ConcurrentAlloc(16));
                    v.push_back(ConcurrentAlloc((16 + i) % 8192 + 1));
                }
                size_t end1 = clock();

                size_t begin2 = clock();
                for (size_t i = 0; i < ntimes; i++)
                {
                    // 完全保留您的并发释放调用
                    ConcurrentFree(v[i]);
                }
                size_t end2 = clock();
                v.clear();

                malloc_costtime += (end1 - begin1);
                free_costtime += (end2 - begin2);
            }
            });
    }

    for (auto& t : vthread)
    {
        t.join();
    }
    // 安全获取原子值
    size_t malloc_time = malloc_costtime.load();
    size_t free_time = free_costtime.load();
    size_t total_ops = nworks * rounds * ntimes;

    // 使用%zu格式说明符打印size_t类型
    printf("%zu个线程并发执行%zu轮次，每轮次concurrent alloc %zu次: 花费：%zu ms\n",
        nworks, rounds, ntimes, malloc_time);

    printf("%zu个线程并发执行%zu轮次，每轮次concurrent dealloc %zu次: 花费：%zu ms\n",
        nworks, rounds, ntimes, free_time);

    printf("%zu个线程并发concurrent alloc&dealloc %zu次，总计花费：%zu ms\n",
        nworks, total_ops, malloc_time + free_time);
}
int main()
{
	size_t n = 1000;
	cout << "==========================================================" << endl;
    BenchmarkMalloc(n, 4, 10);
	cout << endl << endl;

	BenchmarkConcurrentMalloc(n, 10, 10);
	cout << "==========================================================" << endl;

	return 0;
}